package com.lebang.medicalInquiry.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.lebang.medicalInquiry.component.TokenComponent;
import com.lebang.medicalInquiry.constant.BusinessEnum;
import com.lebang.medicalInquiry.constant.ConfigEnum;
import com.lebang.medicalInquiry.constant.ResponseEnum;
import com.lebang.medicalInquiry.constant.annotation.Require;
import com.lebang.medicalInquiry.model.po.ConsultationSheet;
import com.lebang.medicalInquiry.model.vo.UserTokenVo;
import com.lebang.medicalInquiry.response.Callback;
import com.lebang.medicalInquiry.response.JsonData;
import com.lebang.medicalInquiry.service.ConfigService;
import com.lebang.medicalInquiry.service.PayService;
import com.lebang.medicalInquiry.utils.TextUtil;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.service.payments.model.Transaction;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

@RequestMapping("/api/pay")
@Api(tags = "支付相关")
@RestController
@Validated
public class PayApi {

    @Autowired
    private TokenComponent tokenComponent;

    @Autowired
    private ConfigService configService;

    @Autowired
    private PayService payService;

    /**
     * 创建支付订单
     *
     * @param request
     * @param response
     * @param type
     * @return
     */
    @Require
    @ApiOperation("创建会员充值支付订单")
    @RequestMapping(value = "/createOrder", method = {RequestMethod.POST})
    public JsonData createOrder(HttpServletRequest request, HttpServletResponse response,
                                @ApiParam(name = "consultationSheetId", value = "问诊单id", example = "1") @NotNull(message = "问诊单id必传")
                                @RequestParam(name = "consultationSheetId", required = false) Integer consultationSheetId,
                                @ApiParam(name = "payType", value = "支付类型 pay,refund", example = "pay")
                                @NotNull(message = "支付类型必传")
                                @RequestParam(name = "payType", required = false) String payType,
                                @ApiParam(name = "type", value = "充值类型1:支付宝,2:微信", example = "1")
                                @NotNull(message = "充值类型必传")
                                @RequestParam(name = "type", required = false) Integer type
    ) {


        UserTokenVo member = tokenComponent.getMember(request);

        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo(), payService.payService(consultationSheetId, member.getUuid(), payType, type));

    }


    /**
     * 支付宝的回调接口
     *
     * @param request
     * @param response
     * @return
     */

    @ApiOperation("支付宝回调")
    @RequestMapping(value = "/zfb/notify", method = {RequestMethod.POST})
    public String zfbPayNotify(HttpServletRequest request, HttpServletResponse response
    ) {


        try {
            String content = configService.getByCode(BusinessEnum.AliPay.getType());

            Map config = (Map) JSON.parse(content);
            //获取支付宝POST过来反馈信息
            Map<String, String> params = new HashMap<>(16);
            Map<String, String[]> requestParams = request.getParameterMap();

            for (String name : requestParams.keySet()) {
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                params.put(name, valueStr);
            }

            String s = params.get("trade_status");
            //调用SDK验证签名
            boolean signVerified = false;

            signVerified = AlipaySignature.rsaCheckV1(params, config.get("aliPayPublicKey").toString(), config.get("charset").toString(), config.get("signType").toString());

            //验证成功
            if (signVerified) {

                if ("TRADE_SUCCESS".equals(s)) {

                    String orderNo = params.get("out_trade_no");
                    String zfbTradeNo = params.get("trade_no");
                    if (TextUtil.isEmpty(orderNo)) {
                        return "fail";
                    }
                    boolean isSuccess = payService.paySuccess(orderNo, zfbTradeNo);
                    if (isSuccess) {
                        return "success";
                    }
                }
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "fail";
    }


    /**
     * 支付宝的回调接口
     *
     * @param request
     * @param response
     * @return
     */

    @ApiOperation("微信支付回调")
    @RequestMapping(value = "/wx/notify", method = {RequestMethod.POST})
    public Map wxPayNotify(HttpServletRequest request, HttpServletResponse response
    ) {

        String byCode = configService.getByCode(ConfigEnum.WXPAY.getConfigType());
        JSONObject jsonObject = JSONObject.parseObject(byCode);
        String merchantId = jsonObject.getString("merchantId");
        String privateKey = jsonObject.getString("privateKey");
        String merchantSerialNumber = jsonObject.getString("merchantSerialNumber");
        String apiV3Key = jsonObject.getString("apiV3Key");
        Map<String, String> responseMap = new HashMap<>();
        try {
            String wxSignature = request.getHeader("Wechatpay-Signature");
            String wxSerial = request.getHeader("Wechatpay-Serial");
            String wxNonce = request.getHeader("Wechatpay-Nonce");
            String wxTimestamp = request.getHeader("Wechatpay-Timestamp");
            StringBuffer sb = new StringBuffer();
            BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            com.wechat.pay.java.core.notification.RequestParam requestParam = new com.wechat.pay.java.core.notification.RequestParam.Builder()
                    .serialNumber(wxSerial)
                    .nonce(wxNonce)
                    .signature(wxSignature)
                    .timestamp(wxTimestamp)
                    .body(sb.toString())
                    .build();
            RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(merchantId)
                    .privateKey(privateKey)
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(apiV3Key)
                    .build();
            NotificationParser parser = new NotificationParser(config);
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            Transaction.TradeStateEnum tradeState = transaction.getTradeState();
            if (tradeState.name().equals(Transaction.TradeStateEnum.SUCCESS.name())) {
                boolean isSuccess = payService.paySuccess(transaction.getOutTradeNo(), transaction.getTransactionId());
                if (isSuccess) {
                    responseMap.put("code", "SUCCESS");
                    responseMap.put("message", "成功");
                    return responseMap;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        responseMap.put("code", "FAIL");
        responseMap.put("message", "失败");
        return responseMap;
    }

    /**
     * 查询订单支付状态
     *
     * @param request
     * @param response
     * @param orderNo
     * @return
     */
    @Require
    @ApiOperation("查询订单支付状态")
    @RequestMapping(value = "/order/state", method = {RequestMethod.POST})
    public JsonData query(HttpServletRequest request, HttpServletResponse response,
                          @ApiParam(name = "orderNo", value = "订单号", required = true)
                          @NotNull(message = "订单号不允许为空") @RequestParam(name = "orderNo") String orderNo
    ) {

        boolean isSuccess = payService.queryByOrder(orderNo);
        return Callback.success(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMemo(), isSuccess);

    }
}
